package xframe.util;

import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;

/**
 * �ý��۸� :
 * ���α׷���:
 * ���α׷� ���� : Velocity�� ��ȯ�ϴ� Ŭ����
 * version : 1.0
 * �ۼ��� : 2005. 7. 14.  ���� 6:11:17
 * <p/>
 * �ۼ���: ���鼮
 * Ư�̻���:
 * Version ������� :
 */
public class VTLTranslator {

    static Logger log = Logger.getLogger(VTLTranslator.class);

    
    /**
     * @see String :  Hash�� ������ Key ���� ��� ���ν�Ű�� �Լ�
     * @param velocityString  : xml���� �о�帰 ���ڿ�
     * @param key  : ��ȯ�� key ��
     * @param value  : ��ȯ�� value ��
     * @return String :  VTL�� �����ϵ� ���ڿ� ��ȯ
     */
    public static String getDecodeByString(String velocityString, String key, String value){
        // System.out.println("velocityString:"+velocityString);
        //  VelocityEngine ve = new VelocityEngine();

        VelocityContext context = new VelocityContext();
        try {
            if(velocityString.trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no input String.");
            }
            Velocity.init();
          // UtilMaster.consoleOut("xframe.console.VTL.Read.show","Read the VTL  statement :\n"+velocityString+"\n\n");
            /*  create a context and add data */
                context.put(key, value);
           /* now render the template into a StringWriter */
            StringWriter writer = new StringWriter();
            String logTag = "VTLTranslator.java";
            Velocity.evaluate( context, writer, logTag, velocityString );
            if(writer.toString().trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no return converted  Strings.");
            }

            //ȭ�鿡 ��ȯ�� ������ �ѷ����� �����ϴ� ����
           // UtilMaster.consoleOut("xframe.console.VTL.Transtlation.show","Translate the VTL statement :\n"+writer.toString());
            return writer.toString();
            /* show the World */
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * @see String :  Collection�� ���� �����ϴ�  �Լ�
     * Ư��, TODO : �� ���Ŀ��� prepatedStatement�� �ǵ��� �����Ѵ�.
     * @param velocityString  : xml���� �о�帰 ���ڿ�
     * @param key  : ��ȯ�� key ��
     * @param index  : ��ȯ�� index ��
     * @return String :  VTL�� �����ϵ� ���ڿ� ��ȯ
     */
    public static String getDecodeByMultiParam(String velocityString, HashMap param, int index){
       // log.info("velocityString:"+velocityString);
        //  VelocityEngine ve = new VelocityEngine();

        VelocityContext context = new VelocityContext();
        try {
            if(velocityString.trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no input String.");
            }
            Velocity.init();
          //UtilMaster.consoleOut("xframe.console.VTL.Read.show","Read the VTL statement :\n"+velocityString);

          // String []key =UtilMaster.getHashKeys(param);

          //  String temp="";
           //
           /*  create a context and add data */

            Set set = param.keySet();
            Object[] obj = set.toArray();
            for(int i = 0 ; i <param.size(); i++){
                if(param.get(obj[i]) instanceof String[]){

                    String values[] = (String[])param.get(obj[i]);
                    context.put((String)obj[i],values[index]);

                }else{
                    context.put((String)obj[i],param.get(obj[i]));
                }
            }



            /* now render the template into a StringWriter */
            StringWriter writer = new StringWriter();
            String logTag = "VTLTranslator.java";
            Velocity.evaluate( context, writer, logTag, velocityString );
            if(writer.toString().trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no return converted  Strings.");
            }

            return writer.toString();
            /* show the World */
        } catch (Exception e) {
            e.printStackTrace();

        }
        return null;
    }

    /**
     * @see String :  Collection�� ���� �����ϴ�  �Լ�
     * Ư��, TODO : �� ���Ŀ��� prepatedStatement�� �ǵ��� �����Ѵ�.
     * @param velocityString  : xml���� �о�帰 ���ڿ�
     * @param param  : ��ȯ�� key ��
     * @return String :  VTL�� �����ϵ� ���ڿ� ��ȯ
     */
    public static String getDecodeByCollection(String velocityString, HashMap param) throws XMLQueryException {
        //log.info("velocityString:"+velocityString);
       //  VelocityEngine ve = new VelocityEngine();

        VelocityContext context = new VelocityContext();
        try {
            if(velocityString.trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no input String.");
            }
            Velocity.init();
            // UtilMaster.consoleOut("xframe.console.VTL.Read.show","Read the VTL statement :\n"+velocityString);

          // String []key =UtilMaster.getHashKeys(param);

          //  String temp="";
             context.put("QUERY_RESULT", param);
           //  System.out.println("*****************QUERY_RESULT");
           /* for(int i = 0 ; i < key.length ; i++){
               if(key[i].equals("QUERY_RESULT")){
                   context.put(key[i], param);
                   System.out.println("*****************QUERY_RESULT");
                   System.out.println(key[i]+"="+param);
               }else{
                   context.put(key[i], param.get(key[i]));
                   System.out.println(key[i]+"="+param.get(key[i]));
                   //  log.info("Your HashKey :\n"+key[i]+"="+param.get(key[i]));
               }


           }*/



            /* now render the template into a StringWriter */
            StringWriter writer = new StringWriter();
            String logTag = "VTLTranslator.java";
            Velocity.evaluate( context, writer, logTag, velocityString );
            if(writer.toString().trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no return converted  Strings.");
            }
              // UtilMaster.consoleOut("xframe.console.VTL.Transtlation.show","Translate the VTL statement :\n"+writer.toString());

            return writer.toString();
            /* show the World */
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * @see String :  request �Ķ���͸� VTL�� ��ȯ�ϴ� �Լ�
     * @param velocityString  : xml���� �о�帰 ���ڿ�
     * @param request  : HttpServletRequest
     * @return String :  VTL�� �����ϵ� ���ڿ� ��ȯ
     */
    
   public static String getDecode(String velocityString, HttpServletRequest request){
      VelocityContext context = new VelocityContext();
        try {
            if(velocityString.trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no input String.");
            }
            Velocity.init();
            // UtilMaster.consoleOut("xframe.console.VTL.Read.show","Read the VTL statement :\n"+velocityString);
          // HashMap param =AutoMapper.getParam(request);
            context.put("request", request);


            /*  create a context and add data */
            StringWriter writer = new StringWriter();
            String logTag = "VTLTranslator.java";
            Velocity.evaluate( context, writer, logTag, velocityString );
            if(writer.toString().trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no return converted  Strings.");
            }
            //UtilMaster.consoleOut("xframe.console.VTL.Translation.show","Translate the VTL statement :\n"+writer.toString());
            return writer.toString();
            /* show the World */
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
   }

   
   /**
    * @see String :  request�� respose��  VTL�� ��ȯ�ϴ� �Լ�
    * @param velocityString  : xml���� �о�帰 ���ڿ�
    * @param request  : HttpServletRequest
    * @param response  : HttpServletResponse
    * @return String :  VTL�� �����ϵ� ���ڿ� ��ȯ
    */
    public static String getDecode(String velocityString, HttpServletRequest request, HttpServletResponse response){
      VelocityContext context = new VelocityContext();
        try {
            if(velocityString.trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no input String.");
            }
            Velocity.init();
            // UtilMaster.consoleOut("xframe.console.VTL.Read.show","Read the VTL statement :\n"+velocityString);
          // HashMap param =AutoMapper.getParam(request);
            context.put("request", request);
            context.put("response", response);


            /*  create a context and add data */
            StringWriter writer = new StringWriter();
            String logTag = "VTLTranslator.java";
            Velocity.evaluate( context, writer, logTag, velocityString );
            if(writer.toString().trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no return converted  Strings.");
            }
            //UtilMaster.consoleOut("xframe.console.VTL.Translation.show","Translate the VTL statement :\n"+writer.toString());
            return writer.toString();
            /* show the World */
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
   }

    
    /**
     * @see String :  Hash�� ������ Key ���� ��� ���ν�Ű�� �Լ�
     * @param velocityString  : xml���� �о�帰 ���ڿ�
     * @param param  : HashMap
     * @return String :  VTL�� �����ϵ� ���ڿ� ��ȯ
     */
    public static String getDecode(String velocityString, HashMap param){
        // System.out.println("velocityString:"+velocityString);
        //  VelocityEngine ve = new VelocityEngine();

        VelocityContext context = new VelocityContext();
        try {
            if(velocityString.trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no input String.");
            }
            Velocity.init();
            // UtilMaster.consoleOut("xframe.console.VTL.Read.show","Read the VTL statement :\n"+velocityString);

            setContext(param, context);

            /* now render the template into a StringWriter */
            StringWriter writer = new StringWriter();
            String logTag = "VTLTranslator.java";
          //  Object[] obj = context.getKeys();

          //  for(int i = 0 ; i < obj.length ;i++){
              //  System.out.println("obj:"+obj[i]);
         //   }
            Velocity.evaluate( context, writer, logTag, velocityString );
            if(writer.toString().trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no return converted  Strings.");
            }
            boolean convertShow = UtilMaster.null2Boolean(DynamicVar.get("xframe.console.toKor.show","false"));
            String convertingStr = null;
             if(convertShow){
                convertingStr = UtilMaster.toKor(writer.toString());
            }else{
                convertingStr = writer.toString();
            }

            UtilMaster.consoleOut("xframe.console.VTL.Translation.show","Translate the VTL statement :\n"+convertingStr);


            return writer.toString();
            /* show the World */
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    
    /**
     * @see String :  Hash�� ������ Key ���� ��� ���ν�Ű�� �Լ�
     * @param velocityString  : xml���� �о�帰 ���ڿ�
     * @param param  : HashMap
     * @param index  : 
     * @return String :  VTL�� �����ϵ� ���ڿ� ��ȯ
     */
    public static String getDecode(String velocityString, HashMap param, int index){
        // System.out.println("velocityString:"+velocityString);
        //  VelocityEngine ve = new VelocityEngine();

        VelocityContext context = new VelocityContext();
        try {
            if(velocityString.trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no input String.");
            }
            Velocity.init();
            // UtilMaster.consoleOut("xframe.console.VTL.Read.show","Read the VTL statement :\n"+velocityString);

            setContext(param, context, index);

            /* now render the template into a StringWriter */
            StringWriter writer = new StringWriter();
            String logTag = "VTLTranslator.java";
            Velocity.evaluate( context, writer, logTag, velocityString );
            if(writer.toString().trim().length()==0){
                throw new XMLQueryException("[VTLTranslator Error] There is no return converted  Strings.");
            }
            boolean convertShow = UtilMaster.null2Boolean(DynamicVar.get("xframe.console.toKor.show","false"));
            String convertingStr = null;
             if(convertShow){
                convertingStr = UtilMaster.toKor(writer.toString());
            }else{
                convertingStr = writer.toString();
            }

            UtilMaster.consoleOut("xframe.console.VTL.Translation.show","Translate the VTL statement :\n"+convertingStr);


            return writer.toString();
            /* show the World */
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @see String :  �ĸ�(')�� ���ؼ� ����� ������ �������� Ư�� ���ڷ� ��ȯ�ϰ����Ҷ� ���ȴ�. 
     * @param param  : HashMap
     * @param context  : VelocityContext
     * @return String :  VTL�� �����ϵ� ���ڿ� ��ȯ
     */
    private static void setContextBackup(HashMap param, VelocityContext context) throws XMLQueryException {
        boolean requestConvertChar =false;
        //requestConvertChar = UtilMaster.null2Boolean(DynamicVar.get("xframe.request.comma.convertChar","false"));

        /*  create a context and add data */
        Set set = param.keySet();
        Object[] obj = set.toArray();
        
        
        String  encordingFrom ="";
        String  encordingTo ="";
        String encordingStr = "";
        
    	//encordingFrom = UtilMaster.null2Default(DynamicVar.get("xframe.database.encoding.from"),"8859_1"); 
    	//encordingTo = UtilMaster.null2Default(DynamicVar.get("xframe.database.encoding.to"),"KSC5601"); 
    	String param_string ="";
    	String key ="";
    	//System.out.println("xframe.database.encoding.from :" + encordingFrom +", xframe.database.encoding.to:"+encordingTo );
    	for(int i = 0 ; i <param.size(); i++){
            //if(requestConvertChar){
            //    context.put(((String)obj[i]).replace('.','_'), UtilMaster.replace((String)param.get(obj[i]),"'",DynamicVar.get("xframe.request.comma.convertChar")));
            //}else{
                 context.put(((String)obj[i]).replace('.','_'), param.get(obj[i]));
            //}
           // System.out.println(((String)obj[i]).replace('.','_')+"==>"+param.get(obj[i]));
          // System.out.println(((String)obj[i]).replace('.','_')+"    context   ===>"+context.get(((String)obj[i]).replace('.','_')));
        }
    }
    
    private static void setContext(HashMap param, VelocityContext context) throws XMLQueryException {
    	boolean requestConvertChar =false;
    	//requestConvertChar = UtilMaster.null2Boolean(DynamicVar.get("xframe.request.comma.convertChar","false"));
    	
    	/*  create a context and add data */
    	Set set = param.keySet();
    	Object[] obj = set.toArray();
    	
    	
    	String  encordingFrom ="";
    	String  encordingTo ="";
    	String encordingStr = "";
        boolean encoding = false;
		encoding	=	"true".equalsIgnoreCase(DynamicVar.get("xframe.database.encoding"));
		if(encoding){
			encordingTo = UtilMaster.null2Default(DynamicVar.get("xframe.database.encoding.from"),"8859_1");
			encordingFrom = UtilMaster.null2Default(DynamicVar.get("xframe.database.encoding.to"),"KSC5601"); 
		}
    	
    	String param_string ="";
    	String key ="";
    	//System.out.println("xframe.database.encoding.from :" + encordingFrom +", xframe.database.encoding.to:"+encordingTo );
    	for(int i = 0 ; i <param.size(); i++){
    		key = (String)obj[i];
    		
	    		
	    		if(param.get(obj[i]) instanceof String){
	    			param_string = (String)param.get(obj[i]);
	    		
		    		try {
		    			//System.out.println("param_string:" + param_string  );
		    			if(encoding){
			    			if(param_string != null){
			    				encordingStr = new String(param_string.getBytes(encordingFrom),encordingTo);
			    			}else{
			    				//encordingStr = new String(param_string.getBytes(encordingFrom),encordingTo);
			    			}
		    			}else{
		    				encordingStr = param_string;
		    			}
		    		} catch (UnsupportedEncodingException e) {
		    			e.printStackTrace();
		    		}
		    		
		    		
		    		
		    		//System.out.println("key :" + key.replace(xframe.conf.Constants.TEMP_KEY_SET, "") +", encordingStr:"+encordingStr );
		    		context.put(key.replace(xframe.conf.Constants.TEMP_KEY_SET, ""), encordingStr);
	    		}else{
	    			context.put(key.replace(xframe.conf.Constants.TEMP_KEY_SET, ""), param.get(obj[i]));
	    		}
    	}
    	
    	
    	//for(int i = 0 ; i <param.size(); i++){
    		//context.put(((String)obj[i]).replace('.','_'), param.get(obj[i]));
    	//}
    }
    
    private static void setContext111(HashMap param, VelocityContext context) throws XMLQueryException {
    	boolean requestConvertChar =false;
    	//requestConvertChar = UtilMaster.null2Boolean(DynamicVar.get("xframe.request.comma.convertChar","false"));
    	
    	/*  create a context and add data */
    	Set set = param.keySet();
    	Object[] obj = set.toArray();
    	
    	
    	String  encordingFrom ="";
    	String  encordingTo ="";
    	String encordingStr = "";
        boolean encoding = false;
		encoding	=	"true".equalsIgnoreCase(DynamicVar.get("xframe.database.encoding"));
		if(encoding){
			encordingTo = UtilMaster.null2Default(DynamicVar.get("xframe.database.encoding.from"),"8859_1");
			encordingFrom = UtilMaster.null2Default(DynamicVar.get("xframe.database.encoding.to"),"KSC5601"); 
		}
		
    	String param_string ="";
    	String key ="";
    	
    	//System.out.println("xframe.database.encoding.from :" + encordingFrom +", xframe.database.encoding.to:"+encordingTo );
    	for(int i = 0 ; i <param.size(); i++){
    		//System.out.println("파라미터가 "+obj[i]);
    		if(param.get(obj[i]) instanceof String){
    			//System.out.println("파라미터가 String 이다.");
    			key = (String)obj[i];
        		if(encoding){
        			//System.out.println("파라미터가 String 이다.");
        			param_string	=	(String)param.get(key);
                	if(param_string != null){
        				try {
        					//charSet(param_string);
    						encordingStr = new String(param_string.getBytes(encordingFrom),encordingTo);
    					} catch (UnsupportedEncodingException e) {
    						e.printStackTrace();
    					}
        			}else{
        				encordingStr = null;
        			}
            	}else{
            		encordingStr = param_string;
            	}
        		
        		System.out.println("key :" + key +", encordingStr:"+encordingStr );
        		context.put(key, encordingStr);
    		}else{
    			//System.out.println("파라미터가 String[] 이다.");
    			key = (String)obj[i];
    			//System.out.println("파라미터가 String[] 이다.");
    	        set = param.keySet();
    	        obj = set.toArray();
    	        for(int k = 0 ; k <param.size(); k++){
	                String values[] = (String[])param.get(obj[k]);
	                context.put((String)obj[i],values);
    	        }
    			
    		}

    		
    	}
    	
    	
    	//for(int i = 0 ; i <param.size(); i++){
    		//context.put(((String)obj[i]).replace('.','_'), param.get(obj[i]));
    	//}
    }

    
    /**
     * @see String :  �÷��� ��ü�� ����� ��ü�� VTL�� ��ȯ�ϱ����� �Լ� 
     * @param param  : HashMap
     * @param context  : VelocityContext
     * @param index  : VelocityContext�÷��� ��ü�� index 
     */
    private static void setContext(HashMap param, VelocityContext context, int index) throws XMLQueryException {
        boolean requestConvertChar = false;
        requestConvertChar = UtilMaster.null2Boolean(DynamicVar.get("xframe.request.comma.convertChar","false"));

        /*  create a context and add data */
        Set set = param.keySet();
        Object[] obj = set.toArray();
        for(int i = 0 ; i <param.size(); i++){
            String temp  = ((String[])param.get(obj[i]))[index];
            //if(requestConvertChar){
               // System.out.println("index : "+ index+"  : "+temp);
                //context.put((String)obj[i], UtilMaster.replace(temp,"'",DynamicVar.get("xframe.request.comma.convertChar")));
            //}else{
               //  System.out.println("index : "+ index+"  : "+temp);
                 context.put((String)obj[i],temp);
            //}
        }
    }

    /**
     * @see String :  request�� �Ѱ��� ��ü�� VTL�� ��ȯ�ϱ� ���� �Լ�
     * @param request  : HttpServletRequest
     * @param context  : VelocityContext 
     */
    public static void setContext(HttpServletRequest request, VelocityContext context) throws XMLQueryException {
        HashMap hm = new HashMap();
        hm =AutoMapper.getAttribues(request);
       // String key[] = UtilMaster.getHashKeys(hm);
       setContext(hm, context);
    }
}

